package com.xtaller.sdboot.core.base.impl;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.core.base.BaseService;
import com.xtaller.sdboot.core.helper.BeanHelper;
import com.xtaller.sdboot.core.helper.ContextHelper;
import com.xtaller.sdboot.core.helper.SqlExecutorHelper;
import com.xtaller.sdboot.utils.annotation.BindEntity;
import com.xtaller.sdboot.utils.annotation.BindEntityList;
import com.xtaller.sdboot.utils.helper.*;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.var;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : Taller
 * @date : 2020/1/14 23:50
 * @Description :
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {
    private Class<T> cls;
    private BaseService baseService;
    /***
     * 获取当前的Mapper对象
     * @return
     */
    protected M getMapper(){
        return baseMapper;
    }

    @Override
    public T get(Serializable id) {
        var model = super.getById(id);
        return model;
    }
    @Override
    public T get(Wrapper<T> wrapper) {
        return super.getOne(wrapper);
    }

    /**
     * 传入什么对象返回什么对象
     * */
    @Override
    public Object get(Serializable id, Class clz) {
        var model = super.getById(id);
        var data = JsonHelper.o2j(model);
        if(model != null){
            Field[] fields = clz.getDeclaredFields();

            for(Field field: fields){
                System.out.println(field);
                // 判断绑定类型
                if(field.isAnnotationPresent(BindEntityList.class)){
                    var fieldName = field.getName();
                    var bel = field.getAnnotation(BindEntityList.class);
                    // 实体类
                    Class<T> cla = bel.entity();
                    // 中间表
                    var middle = bel.middle();
                    // 关联条件
                    var correlations = bel.correlation().split(":");
                    // 读取的字段
                    var column = bel.column();
                    // 获取服务
                    var service = ContextHelper.getBaseServiceByEntity(cla);
                    var param = Arrays.asList(id);
                    data.put(fieldName, getCorrelationData(cla, service, param, middle, correlations, column));
                }

//                if(field.isAnnotationPresent(BindDict.class)){
//                    var fieldName = field.getName();
//                    var bd = field.getAnnotation(BindDict.class);
//                    // 读取类型
//                    var tv = bd.type_value();
//                    // 实体类
//                    Class<T> cla = (Class<T>) DataDict.class;
//                    // 获取服务
//                    var service = ContextHelper.getBaseServiceByEntity(cla);
//                    // 读取的字段
//                    var column = bd.column();
//
//                    var w1 = JsonHelper.create("column", "type").put("value", tv);
//                    var w2 = JsonHelper.create("column", "item_value").put("value", data.get(bd.fk_column()));
//                    var wheres = JsonHelper.list(w1, w2);
//
//                    data.put(fieldName, getKVData(cla, service, column, wheres));
//                }

                if(field.isAnnotationPresent(BindEntity.class)){
                    var fieldName = field.getName();
                    var be = field.getAnnotation(BindEntity.class);
                    // 读取类型
                    var tv = be.type_value();
                    // 实体类
                    Class<T> cla = be.entity();
                    // 获取服务
                    var service = ContextHelper.getBaseServiceByEntity(cla);
                    // 读取的字段
                    var column = be.column();

                    var w1 = JsonHelper.create("column", "type").put("value", tv);
                    var w2 = JsonHelper.create("column", "item_value").put("value", data.get(be.fk_column()));
                    var wheres = JsonHelper.list(w1, w2);

                    data.put(fieldName, getKVData(cla, service, column, wheres));
                }
            }
            return data;
        }
        return null;
    }



    @Override
    public List<T> getByIds(List ids) {
        QueryWrapper<T> where = new QueryWrapper<>();
        where.in("id", ids);
        return super.list(where);
    }

//    public List<JSONObject> getByIds(List ids, Class clz) {
//        QueryWrapper<T> where = new QueryWrapper<>();
//        var list = super.list(where);
//        if(list.size() > 0){
//            var data = JsonHelper.o2l(list);
//            Field[] fields = clz.getDeclaredFields();
//
//            for(Field field: fields){
//                System.out.println(field);
//                // 判断绑定类型
//                if(field.isAnnotationPresent(BindEntityList.class)){
//                    var fieldName = field.getName();
//                    var bel = field.getAnnotation(BindEntityList.class);
//                    // 实体类
//                    Class<T> cla = bel.entity();
//                    // 中间表
//                    var middle = bel.middle();
//                    // 关联条件
//                    var correlations = bel.correlation().split(":");
//                    // 读取的字段
//                    var column = bel.column();
//                    // 获取服务
//                    var service = ContextHelper.getBaseServiceByEntity(cla);
//                    // 获取Id
//
//                    var param = Arrays.asList(id);
//                    data.put(fieldName, getCorrelationData(cla, service, param, middle, correlations, column));
//                }
//
//                if(field.isAnnotationPresent(BindDict.class)){
//                    var fieldName = field.getName();
//                    var bd = field.getAnnotation(BindDict.class);
//                    // 读取类型
//                    var tv = bd.type_value();
//                    // 实体类
//                    Class<T> cla = (Class<T>) DataDict.class;
//                    // 获取服务
//                    var service = ContextHelper.getBaseServiceByEntity(cla);
//                    // 读取的字段
//                    var column = bd.column();
//
//                    var w1 = JsonHelper.create("column", "type").put("value", tv);
//                    var w2 = JsonHelper.create("column", "item_value").put("value", data.get(bd.fk_column()));
//                    var wheres = JsonHelper.list(w1, w2);
//
//                    data.put(fieldName, getKVData(cla, service, column, wheres));
//                }
//
//                if(field.isAnnotationPresent(BindEntity.class)){
//                    var fieldName = field.getName();
//                    var be = field.getAnnotation(BindEntity.class);
//                    // 读取类型
//                    var tv = be.type_value();
//                    // 实体类
//                    Class<T> cla = be.entity();
//                    // 获取服务
//                    var service = ContextHelper.getBaseServiceByEntity(cla);
//                    // 读取的字段
//                    var column = be.column();
//
//                    var w1 = JsonHelper.create("column", "type").put("value", tv);
//                    var w2 = JsonHelper.create("column", "item_value").put("value", data.get(be.fk_column()));
//                    var wheres = JsonHelper.list(w1, w2);
//
//                    data.put(fieldName, getKVData(cla, service, column, wheres));
//                }
//            }
//            return data;
//        }
//        return JsonHelper.list();
//    }

    @Override
    public boolean create(T entity) {
        if(entity == null){
            return false;
        }
        return super.save(entity);
    }

    @Override
    public boolean model(T entity) {
        return super.saveOrUpdate(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean model(Collection entityList) {
        if(ValidatorHelper.isEmpty(entityList)){
            warning("createOrUpdateEntities", "参数entityList为空!");
            return false;
        }
        // 批量插入
        return super.saveOrUpdateBatch(entityList, 100);
    }

    @Override
    public boolean update(T entity) {
        boolean success = super.updateById(entity);
        return success;
    }

    @Override
    public boolean update(T entity, Wrapper<T> updateWrapper) {
        boolean success = super.update(entity, updateWrapper);
        return success;
    }

    @Override
    public boolean update(Wrapper updateWrapper) {
        boolean success = super.update(null, updateWrapper);
        return success;
    }

    @Override
    public boolean delete(Serializable id) {
        boolean success = super.removeById(id);
        return success;
    }

    @Override
    public boolean delete(Wrapper queryWrapper) {
        return super.remove(queryWrapper);
    }

    @Override
    public List<T> getList(Wrapper queryWrapper) {
        return super.list(queryWrapper);
    }

    @Override
    public IPage<T> pages(IPage<T> page, Wrapper<T> qw) {
        return super.page(page, qw);
    }


    @Override
    public IPage<T> pages(IPage<T> page) {
        return super.page(page);
    }

    /**
     * 获取Entity的class
     * @return
     */
    protected Class<T> getEntityClass(){
        if(this.cls == null){
            this.cls = BeanHelper.getGenericityClass(this.getClass(), 1);
        }
        return this.cls;
    }

    /**
     * 获取关联关系数据 1:n关系
     * */
    private List getCorrelationData(Class<T> entity, BaseService service, List<Serializable> param, String middle, String[] correlations, String column){
        var sqlField = " " + correlations[0] + "," + correlations[1] + " ";
        var sqlForm = " " + middle + " ";
        var sqlWhere = " " + correlations[0] + " ";
        try{
            var list = SqlExecutorHelper.executeQuery("SELECT " +
                    sqlField +
                    "FROM " +
                    sqlForm +
                    "WHERE " +
                    sqlWhere +" IN (?)", param);
            var str = JsonHelper.stringify(list);
            var data = JsonHelper.parseArray(str, JSONObject.class);

            var ids = data.stream().map(x -> x.get(correlations[1])).collect(Collectors.toList());
            QueryWrapper<T> wrapper = new QueryWrapper();
            wrapper.select(column).in("id", ids);

            return service.getList(wrapper);
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 获取关联关系数据 1:1关系
     * */
    public JSONObject getKVData(Class<T> entity, BaseService service, String select, List<JSONObject> wheres){
        QueryWrapper<T> wrapper = new QueryWrapper();
        wrapper.select(select);
        if(wheres.size() > 0){
            for(JSONObject where : wheres){
                wrapper.select(select).eq(where.getString("column"), where.get("value"));
                //System.out.println("wrapper=" + wrapper.getSqlSelect());
            }
        }
        System.out.println("service=" + service.getClass().getName());
        System.out.println("wrapper=" + wrapper.getCustomSqlSegment());
        var list = service.getList(wrapper);
        if(list.size() > 0){
            return JsonHelper.o2j(list.get(0));
        }else {
            return null;
        }
    }

    /***
     * 打印警告信息
     * @param method
     * @param message
     */
    private void warning(String method, String message){
        log.warn(this.getClass().getName() + "."+ method +" 调用错误: "+message+", 请检查！");
    }
}
